﻿using NSubstitute;
using Sai.Core;
using Sai.Core.Rules;
using Sai.Test.TestDataBuilders;
using Sai.Test.XUnit;
using Xunit;

namespace Sai.Test.Rules
{
    public class CheckTypeFinalizerFacts
    {
        [Fact, TouchingFileSystemTest]
        public void Adding_Finalizer_Is_Flagged()
        {
            const string className = "Class1";

            var oldClassBuilder = CompilableClassBuilder.PublicClass()
                .Named(className);

            string oldCode = BoilerPlateCodeBuilder.BuildFor(oldClassBuilder);

            var newClassBuilder = CompilableClassBuilder.PublicClass()
                .Named(className)
                .WithFinalizer();

            string newCode = BoilerPlateCodeBuilder.BuildFor(newClassBuilder);

            TypeDifference diff = TypeDifferenceBuilder.Differences()
                .CodeWas(oldCode)
                .CodeIsNow(newCode)
                .CheckedUsing(new CheckTypeFinalizer())
                .Build();

            Assert.True(diff.HasChanged);

            Assert.NotNull(diff.FinalizersAdded);
            Assert.Equal(1, diff.FinalizersAdded.Count);
            Assert.Null(diff.FinalizersRemoved);
        }

        [Fact, TouchingFileSystemTest]
        public void Removing_Finalizer_Is_Flagged()
        {
            const string className = "Class1";

            var oldClassBuilder = CompilableClassBuilder.PublicClass()
                .Named(className)
                .WithFinalizer();

            string oldCode = BoilerPlateCodeBuilder.BuildFor(oldClassBuilder);

            var newClassBuilder = CompilableClassBuilder.PublicClass()
                .Named(className);

            string newCode = BoilerPlateCodeBuilder.BuildFor(newClassBuilder);

            IProductReleaseProject project = Mock.MinimalProject();

            TypeDifference diff = TypeDifferenceBuilder.Differences()
                .CodeWas(oldCode)
                .CodeIsNow(newCode)
                .CheckedUsing(new CheckTypeFinalizer())
                .Build();

            Assert.True(diff.HasChanged);

            Assert.NotNull(diff.FinalizersRemoved);
            Assert.Equal(1, diff.FinalizersRemoved.Count);
            Assert.Null(diff.FinalizersAdded);
        }
    }
}
